//https://movingai.com/benchmarks/street/index.html
//python server.py
class Grid {
    constructor(rows, cols) {
        this.rows = rows;
        this.cols = cols;
        this.start = { x: 6, y: 18 };
        this.end = { x: 14, y: 31 };
        this.generateRandomMap();
        // 存储连通块信息用于荧光轮廓
        this.borderComponents = []; // 存储分析结果
        this.cells = this.createEmptyGrid(); // 存储网格信息
    }

    createEmptyGrid() {
        return Array(this.rows).fill().map((_, x) =>
            Array(this.cols).fill().map((_, y) => ({
                isWall: false,
                x,
                y,
                element: null
            }))
        );
    }

    // 新增清除约束区域标记
    clearVisualization() {
        this.cells.forEach(row => {
            row.forEach(cell => {
                cell.element.className = 'cell' + 
                    (cell.isWall ? ' wall' : '') +
                    (cell.x === this.start.x && cell.y === this.start.y ? ' start' : '') +
                    (cell.x === this.end.x && cell.y === this.end.y ? ' end' : '');
            });
        });
    }

    //逐行随机生成障碍体
    generateRandomMap() {
        this.cells = [];
        for (let i = 0; i < this.rows; i++) {
            const row = [];
            for (let j = 0; j < this.cols; j++) {
                row.push({
                    isWall: Math.random() < 0.3,//随机生成地图:该点是障碍物的概率密度为0.3
                    x: i,
                    y: j,
                    element: null
                });
            }
            this.cells.push(row);
        }
        this.ensureAccessibility();
    }
    //确认起终点不可以是障碍物
    ensureAccessibility() {
        this.cells[this.start.x][this.start.y].isWall = false;
        this.cells[this.end.x][this.end.y].isWall = false;
    }

    // 设置起始点和结束点，并重启地图
    setStartEnd(start, end) {
        // 将传入的起始点参数赋值给对象的 start 属性
        this.start = start;
        // 将传入的结束点参数赋值给对象的 end 属性
        this.end = end;
        // 调用对象的 draw 方法，重新绘制图形或路径
        this.draw();
    }
    //绘制地图
    draw() {
        // 新增起点终点同步(右键)
        document.getElementById('startX').value = this.start.x;
        document.getElementById('startY').value = this.start.y;
        document.getElementById('endX').value = this.end.x;
        document.getElementById('endY').value = this.end.y;
        //
        const container = document.getElementById('grid');
        container.style.gridTemplateColumns = `repeat(${this.cols}, 25px)`;
        container.innerHTML = '';

        // 生成坐标轴
        const yAxis = document.querySelector('.y-axis');
        const xAxis = document.querySelector('.x-axis');
        yAxis.innerHTML = this.cells.map((_, i) => `<span>${i}</span>`).join('');
        xAxis.innerHTML = this.cells[0].map((_, j) => `<span>${j}</span>`).join('');

        // 绘制单元格
        this.cells.forEach((row, i) => {
            row.forEach((cell, j) => {
                const div = document.createElement('div');
                div.className = 'cell';
                div.dataset.x = i;
                div.dataset.y = j;
                div.title = `坐标: (${i}, ${j})`;
                
                if (cell.isWall) div.classList.add('wall');//如果是障碍,那样式应当为障碍样式
                if (i === this.start.x && j === this.start.y) div.classList.add('start');
                if (i === this.end.x && j === this.end.y) div.classList.add('end');
                
                div.addEventListener('click', () => this.toggleWall(cell));
                cell.element = div;
                container.appendChild(div);
            });
        });
    }
    //切换空白与障碍体
    toggleWall(cell) {
        if ((cell.x === this.start.x && cell.y === this.start.y) ||
            (cell.x === this.end.x && cell.y === this.end.y)) return;
            
        cell.isWall = !cell.isWall;
        cell.element.classList.toggle('wall');
    }

    clearVisualization() {
        this.cells.forEach(row => {
            row.forEach(cell => {
                cell.element.className = 'cell' + 
                    (cell.isWall ? ' wall' : '') +
                    (cell.x === this.start.x && cell.y === this.start.y ? ' start' : '') +
                    (cell.x === this.end.x && cell.y === this.end.y ? ' end' : '');
            });
        });
    }

    // 一键清空
    clearAllObstacles() {
        for (let x = 0; x < this.rows; x++) {
            for (let y = 0; y < this.cols; y++) {
                const cell = this.cells[x][y];
                // 保留起点和终点不变
                if (!(x === this.start.x && y === this.start.y) && 
                    !(x === this.end.x && y === this.end.y)) {
                    cell.isWall = false;
                    cell.element.classList.remove('wall');
                    // 清除算法可视化状态
                    cell.element.classList.remove('visited', 'path', 'current');
                    cell.g = Infinity;
                    cell.h = 0;
                    cell.f = Infinity;
                    cell.parent = null;
                }
            }
        }
    
        // 清除所有标记
        this.clearVisualization();
        this.borderComponents = [];
        
        // 清除所有特殊标记
        document.querySelectorAll('.constraint-marker, .a2-marker').forEach(el => el.remove());
        document.querySelectorAll('.external-connected-obstacle, .global-extreme').forEach(el => {
            el.classList.remove('external-connected-obstacle', 'global-extreme', 
                            'global-north', 'global-south', 'global-east', 'global-west');
        });
    }
    //获取地图数据
    getMapData() {
        return this.cells;
    }
}
// 图片上传处理
document.getElementById('mapUpload').addEventListener('change', async (e) => {
    const file = e.target.files[0];
    if (!file) return;

    try {
        const formData = new FormData();
        formData.append('mapImage', file);

        const response = await fetch('http://localhost:5000/upload-map', {
            method: 'POST',
            body: formData
        });

        const result = await response.json();
        
        if (!result.success) {
            throw new Error(result.error || "Server returned error");
        }

        // 验证数据结构
        if (!Array.isArray(result.cells) || 
            result.cells.length !== grid.rows ||
            result.cells[0].length !== grid.cols) {
            throw new Error("Invalid grid dimensions received");
        }

        // 保留起点终点状态
        const oldStart = grid.start;
        const oldEnd = grid.end;
        
        // 更新网格
        grid.cells = result.cells;
        
        // 恢复起点终点
        grid.start = oldStart;
        grid.end = oldEnd;
        grid.cells[oldStart.x][oldStart.y].isWall = false;
        grid.cells[oldEnd.x][oldEnd.y].isWall = false;
        
        grid.draw();
        
    } catch (err) {
        console.error("上传失败:", err);
        alert(`上传失败: ${err.message}`);
    }
});

/**右键菜单逻辑**/
let contextMenuCell = null;

document.getElementById('grid').addEventListener('contextmenu', (e) => {
    e.preventDefault();
    const cell = e.target.closest('.cell');
    if (!cell || cell.classList.contains('wall')) return;

    contextMenuCell = cell;
    const menu = document.getElementById('context-menu');
    menu.style.display = 'block';
    menu.style.left = `${e.pageX}px`;
    menu.style.top = `${e.pageY}px`;
});

// 关闭菜单(右键)
document.addEventListener('click', (e) => {
    if (!e.target.closest('#context-menu')) {
        document.getElementById('context-menu').style.display = 'none';
    }
});

// 设置起点函数(右键)
function setAsStart() {
    const x = parseInt(contextMenuCell.dataset.x);
    const y = parseInt(contextMenuCell.dataset.y);
    grid.start = { x, y };
    grid.draw();
    document.getElementById('startX').value = x;
    document.getElementById('startY').value = y;
}

// 设置终点函数(右键)
function setAsEnd() {//parseInt 是 JavaScript 中的一个全局函数，用于将一个字符串解析成整数。
    const x = parseInt(contextMenuCell.dataset.x);
    const y = parseInt(contextMenuCell.dataset.y);
    grid.end = { x, y };
    grid.draw();
    document.getElementById('endX').value = x;
    document.getElementById('endY').value = y;
}

